const db = uniCloud.databaseForJQL()

const CACHE_CONFIG = {

EXPIRY_TIME: 7 * 24 * 60 * 60 * 1000,

DEFAULT_AVATAR: '@/static/nicPic/m1.png',

DOWNLOAD_TIMEOUT: 15000,

H5_URL_CACHE_KEY: 'h5_avatar_urls'
}

// ========================== 模块私有状态 ==========================
const state = {

nicPic: uni.getStorageSync ('nicPic') || {},

downloading: {}
}

// ========================== 工具函数（私有，封装通用逻辑）==========================
/**

检查缓存是否过期
@param {number} cacheTimestamp - 缓存时间戳（ms）
@returns {boolean} 是否过期
*/
function isCacheExpired (cacheTimestamp) {
if (!cacheTimestamp) return true // 无时间戳视为过期
return Date.now () - cacheTimestamp > CACHE_CONFIG.EXPIRY_TIME
}

/**

多端文件存在性检查（优化：补充 H5 URL 缓存检查）
@param {string} path - 文件路径（App / 小程序）或 URL（H5）
@param {string} type - 缓存类型（temp/saved/h5_url）
@returns {Promise<boolean>} 是否存在且有效
*/
async function checkResourceExists (path, type = 'temp') {
// H5 端：检查 URL 缓存是否存在且未过期
if (process.env.VUE_APP_PLATFORM === 'h5') {
if (type !== 'h5_url' || !path) return false
const h5UrlCache = uni.getStorageSync (CACHE_CONFIG.H5_URL_CACHE_KEY) || {}
return !!h5UrlCache [path] && !isCacheExpired (h5UrlCache [path].timestamp)
}

// 小程序端：用 uni.getFileInfo 检查本地文件
if (['mp-weixin', 'mp-alipay', 'mp-toutiao'].includes (process.env.VUE_APP_PLATFORM)) {
try {
await uni.getFileInfo ({ filePath: path })
return true
} catch (err) {
return false
}
}

// App 端：用 plus.io 检查本地文件（兼容绝对路径 / 相对路径）
if (typeof plus !== 'undefined') {
return new Promise (resolve => {
plus.io.resolveLocalFileSystemURL (
path.startsWith ('_doc/') ? path : `_doc/${path}`, // 补全 App 端默认存储路径
() => resolve (true),
() => resolve (false)
)
})
}

return false
}

/**

通用下载函数（优化：增加 H5 端 URL 缓存）
@param {string} downloadUrl - 头像下载地址
@returns {Promise<string>} 有效资源路径（文件路径 / H5 URL）
*/
async function downloadAvatar (downloadUrl) {
// H5 端：无需下载文件，直接缓存 URL（带时间戳）
if (process.env.VUE_APP_PLATFORM === 'h5') {
const h5UrlCache = uni.getStorageSync (CACHE_CONFIG.H5_URL_CACHE_KEY) || {}
h5UrlCache [downloadUrl] = { timestamp: Date.now () }
uni.setStorageSync (CACHE_CONFIG.H5_URL_CACHE_KEY, h5UrlCache)
return downloadUrl
}

// 非 H5 端：下载文件到临时路径
return new Promise ((resolve, reject) => {
uni.downloadFile ({
url: downloadUrl,
timeout: CACHE_CONFIG.DOWNLOAD_TIMEOUT,
success (res) {
if (res.statusCode === 200) {
resolve (res.tempFilePath)
} else {
reject (new Error (`头像下载失败（状态码：${res.statusCode})`))
}
},
fail (err) {
const errMsg = err.errMsg.includes ('timeout')
? ' 头像下载超时（请检查网络）': `头像下载失败：${err.errMsg}`
reject(new Error(errMsg))
}
})
})
}

/**

从数据库拉取用户头像 URL（优化：增加错误处理和结果缓存）
@param {string} sendUserId - 用户 ID
@returns {Promise<string>} 头像下载地址（或空）
*/
async function fetchAvatarUrlFromDB (sendUserId) {
try {
const res = await db
.collection ('linli-user')
.where ({ userId: sendUserId })
.field ({ nicPic: true })
.limit (1) // 限制 1 条，减少数据传输
.get ()

const avatarUrl = res.data?.[0]?.nicPic || ''
// 缓存数据库拉取的 URL，避免重复查库
if (avatarUrl && !state.nicPic [sendUserId]) {
state.nicPic [sendUserId] = { avatarUrl, timestamp: Date.now () }
updateStorage ()
}
return avatarUrl
} catch (err) {
console.error (`[${sendUserId}] 数据库拉取头像URL失败:`, err)
throw new Error (' 获取头像地址失败，请重试 ')
}
}

/**

更新本地存储（优化：仅在缓存变化时同步，减少性能消耗）
*/
function updateStorage () {
try {
const oldCache = uni.getStorageSync ('nicPic') || {}
// 仅当缓存实际变化时才同步（避免频繁调用 setStorage）
if (JSON.stringify (oldCache) !== JSON.stringify (state.nicPic)) {
uni.setStorageSync ('nicPic', state.nicPic)
}
} catch (err) {
console.error (' 头像缓存存储失败:', err)
uni.showToast ({ title: ' 头像缓存保存失败 ', icon: 'none', duration: 2000 })
}
}

// ========================== 核心对外接口 ==========================
/**

核心：获取用户头像（优先级：永久缓存→有效临时缓存→下载→默认头像）
@param {Object} sendUser - 用户信息
@param {string} sendUser.sendUserId - 用户唯一标识（必传）
@param {string} [sendUser.nicPic] - 头像下载地址（可选，优先于数据库查询）
@returns {Promise<Object>} {url: 有效头像路径，isDefault: 是否使用默认头像}
*/
export async function getNicPic (sendUser) {
// 1. 严格参数校验（避免后续逻辑崩溃）
if (!sendUser || typeof sendUser !== 'object' || !sendUser.sendUserId) {
console.error ('getNicPic 参数错误：缺少 sendUserId')
return { url: CACHE_CONFIG.DEFAULT_AVATAR, isDefault: true }
}

const {sendUserId, nicPic: inputAvatarUrl} = sendUser
let avatarUrl = inputAvatarUrl // 优先使用传入的 URL

// 2. 初始化用户缓存（若不存在）
if (!state.nicPic [sendUserId]) {
state.nicPic [sendUserId] = {}
}
const userCache = state.nicPic [sendUserId]

try {
// 3. 优先使用【永久缓存】（未过期 + 文件存在）
if (userCache.savedPath?.url && !isCacheExpired (userCache.savedPath.timestamp)) {
const isExist = await checkResourceExists (userCache.savedPath.url, 'saved')
if (isExist) {
console.log (`[${sendUserId}] 使用未过期永久缓存`)
return {url: userCache.savedPath.url, isDefault: false}
}
// 永久缓存文件丢失，清除记录
delete userCache.savedPath
updateStorage ()
}

// 4. 次选使用【临时缓存】（未过期 + 文件存在）
if (userCache.tempPath?.url && !isCacheExpired (userCache.tempPath.timestamp)) {
const isExist = await checkResourceExists (userCache.tempPath.url, 'temp')
if (isExist) {
console.log (`[${sendUserId}] 使用未过期临时缓存`)
return {url: userCache.tempPath.url, isDefault: false}
}
// 临时缓存文件丢失，清除记录
delete userCache.tempPath
updateStorage ()
}

// 5. 无有效缓存：获取头像下载地址（优先传入 URL→缓存 URL→数据库查询）
if (!avatarUrl) {
// 先查缓存的 URL，再查数据库
avatarUrl = userCache.avatarUrl || await fetchAvatarUrlFromDB (sendUserId)
}
// 无任何头像地址，返回默认头像
if (!avatarUrl) {
console.log (`[${sendUserId}] 无头像地址，使用默认头像`)
return { url: CACHE_CONFIG.DEFAULT_AVATAR, isDefault: true }
}

// 6. 处理下载：复用已存在的下载 Promise（避免重复下载，优化并发）
if (state.downloading [sendUserId]) {
console.log (`[${sendUserId}] 复用已有下载任务`)
const downloadResult = await state.downloading[sendUserId]
return { url: downloadResult, isDefault: false }
}

// 7. 发起新下载（用 Promise 缓存下载状态，替代轮询）
const downloadPromise = downloadAvatar (avatarUrl)
.then (tempUrl => {
// 更新临时缓存（带时间戳）
userCache.tempPath = { url: tempUrl, timestamp: Date.now () }
userCache.avatarUrl = avatarUrl // 同步缓存下载地址
updateStorage ()
console.log (`[${sendUserId}] 下载完成，已缓存临时路径`)
return tempUrl
})
.catch(err => {
console.error(`[${sendUserId}] 下载失败:, err`)
throw err // 抛出错误，让外层 catch 处理
})

// 存储下载中的 Promise
state.downloading [sendUserId] = downloadPromise

// 等待下载完成并返回
const tempUrl = await downloadPromise
return {url: tempUrl, isDefault: false}

} catch (err) {
// 所有流程失败，返回默认头像（兜底）
uni.showToast ({ title: err.message, icon: 'none', duration: 2000 })
return { url: CACHE_CONFIG.DEFAULT_AVATAR, isDefault: true }

} finally {
// 无论成功 / 失败，清除下载状态（避免锁死）
delete state.downloading [sendUserId]
}
}

/**

保存临时缓存为永久缓存（支持多端）
@param {string} sendUserId - 用户唯一标识
@returns {Promise<{success: boolean, message: string}>} 保存结果
*/
export async function saveNicPicToLocal (sendUserId) {
const userCache = state.nicPic [sendUserId]

// 1. 前置检查：是否有有效临时缓存
if (!userCache?.tempPath?.url || isCacheExpired (userCache.tempPath.timestamp)) {
const msg = ' 无有效临时头像缓存，请先加载头像 '
uni.showToast ({ title: msg, icon: 'none' })
return { success: false, message: msg }
}

// H5 端：无永久文件系统，提示不支持
if (process.env.VUE_APP_PLATFORM === 'h5') {
const msg = 'H5 端不支持保存头像到本地 '
uni.showToast ({ title: msg, icon: 'none' })
return { success: false, message: msg }
}

try {
console.log(`[${sendUserId}] 开始保存永久缓存`)
// 2. 调用 uni.saveFile 保存永久文件（多端通用 API）
const {savedFilePath} = await uni.saveFile ({
tempFilePath: userCache.tempPath.url,
filePath: `avatar/${sendUserId}_${Date.now()}.png` // 自定义永久路径（便于管理）
})

// 3. 更新缓存状态：保存永久路径，清除临时路径（避免冗余）
userCache.savedPath = {url: savedFilePath, timestamp: Date.now () }
delete userCache.tempPath
updateStorage ()

uni.showToast ({title: ' 头像已保存到本地 '})
return { success: true, message: ' 保存成功 ', savedPath: savedFilePath }

} catch (err) {
const errMsg = err.errMsg.includes ('limit')
? ' 本地存储空间不足，请清理后重试 '
: `保存失败：${err.errMsg}`
console.error(`[${sendUserId}] 永久保存失败:`, err)
uni.showToast({ title: errMsg, icon: 'none', duration: 2000 })
return { success: false, message: errMsg }
}
}

/**

获取指定用户的头像缓存信息（外部调试 / 状态判断用）
@param {string} sendUserId - 用户唯一标识
@returns {Object|null} 缓存信息：{ tempPath?, savedPath?, avatarUrl?, timestamp? }
*/
export function getNicPicCacheInfo (sendUserId) {
return state.nicPic [sendUserId] ? { ...state.nicPic [sendUserId] } : null // 深拷贝避免外部修改
}

/**

清除指定用户的头像缓存（支持批量清除）
@param {string|string []} sendUserIds - 单个用户 ID 或用户 ID 数组
@param {boolean} [clearStorage=true] - 是否同步清除本地存储
*/
export function clearNicPicCache (sendUserIds, clearStorage = true) {
const ids = Array.isArray (sendUserIds) ? sendUserIds : [sendUserIds]

ids.forEach(id => {
if (state.nicPic[id]) {
delete state.nicPic[id]
console.log(`[${id}] 头像缓存已清除`)
}
})

// 同步本地存储（可选关闭，用于批量清除时减少性能消耗）
if (clearStorage) {
updateStorage ()
}
}

/**

清除所有过期的头像缓存（主动清理，释放存储空间）
*/
export async function clearExpiredNicPicCache () {
const expiredIds = []

// 1. 筛选过期缓存的用户 ID
Object.entries (state.nicPic).forEach (([sendUserId, cache]) => {
const isSavedExpired = cache.savedPath ? isCacheExpired (cache.savedPath.timestamp) : true
const isTempExpired = cache.tempPath ? isCacheExpired (cache.tempPath.timestamp) : true
// 永久 + 临时缓存都过期，视为整体过期
if (isSavedExpired && isTempExpired) {
expiredIds.push (sendUserId)
}
})

// 2. 清除过期缓存
if (expiredIds.length> 0) {
clearNicPicCache (expiredIds)
console.log (`已清除${expiredIds.length}个用户的过期头像缓存`, expiredIds)
return { success: true, expiredCount: expiredIds.length }
}

return {success: true, expiredCount: 0, message: ' 无过期缓存 '}
}